/*
*	Copyright(c) 2020 lutianming email：641471957@qq.com
*
*	Sheeps may be copied only under the terms of the GNU Affero General Public License v3.0
*/

#include "lcommon.h"

static int api_base64_encode(lua_State* L)
{
	size_t datasz = 0;
	const char* src = lua_tolstring(L, 1, &datasz);
	char* data = base64encode(src, datasz, &datasz);
	if (!data) return 0;

	lua_pushlstring(L, data, datasz);
	free(data);
	return 1;
}

static int api_base64_decode(lua_State* L)
{
	size_t datasz = 0;
	const char* src = lua_tolstring(L, 1, &datasz);
	char* data = base64decode(src, datasz, &datasz);
	if (!data) return 0;
	
	lua_pushlstring(L, data, datasz);
	free(data);
	return 1;
}

static int api_md5_encode_string(lua_State* L)
{
	size_t len = 0;
	const char* src = lua_tolstring(L, 1, &len);
	
	char md5[34] = { 0x0 };
	getstringmd5view(src, len, md5, sizeof(md5));
	lua_pushlstring(L, md5, 32);
	return 1;
}

static int api_md5_encode_file(lua_State* L)
{
	const char* file = lua_tostring(L, 1);
	char md5[34] = { 0x0 };
	getfilemd5view(file, md5, sizeof(md5));
	lua_pushlstring(L, md5, 32);
	return 1;
}

static int api_netaddr_in_config(lua_State* L)
{
	const char* ip = lua_tostring(L, 1);
	long long port = lua_tointeger(L, 2);
	const char* se = lua_tostring(L, 3);
	const char* ke = lua_tostring(L, 4);
	int ret = netaddr_in_config(ip, (int)port, se, ke);
	if (ret == 0)
		lua_pushboolean(L, 1);
	else
		lua_pushboolean(L, 0);
	return 1;
}

static int api_message_game_unpack(lua_State* L)
{
	size_t alen = 0;
	const char* data = lua_tolstring(L, 1, &alen);
	if (alen < 2)
	{
		lua_pushinteger(L, 0);
		lua_pushnil(L);
		return 2;
	}
	u_short clen = ntohs(*(u_short*)data);
	if ((size_t)clen + 2 > alen)
	{
		lua_pushinteger(L, 0);
		lua_pushnil(L);
		return 2;
	}

	lua_pushinteger(L, (long long)clen + 2);
	lua_pushlstring(L, data + 2, clen);
	return 2;
}

static int api_message_game_pack(lua_State* L)
{
	size_t clen = 0;
	const char* data = lua_tolstring(L, 1, &clen);

	size_t plen = clen + 2;
	char* buf = (char*)malloc(plen);
	if (buf == NULL)
		return 0;
	*(u_short*)buf = ntohs((u_short)clen);
	memcpy(buf + 2, data, clen);
	lua_pushlstring(L, buf, plen);
	free(buf);
	return 1;
}

static int api_string_split(lua_State* L)
{
	size_t dlen = 0;
	const char* data = lua_tolstring(L, 1, &dlen);
	size_t splen = 0;
	const char* sp = lua_tolstring(L, 2, &splen);

	lua_newtable(L);
	char* p = NULL;
	char* s = (char*)data;
	int i = 1;
	while ((p = (char*)strstr(s, sp)) != NULL)
	{
		if (p != s)
		{
			*p = 0x0;
			lua_pushnumber(L, i++);
			lua_pushlstring(L, s, p - s);
			lua_settable(L, -3);
			*p = *sp;
		}
		s = p + splen;
	}
	if (s - data < (int)dlen)
	{
		lua_pushnumber(L, i++);
		lua_pushstring(L, s);
		lua_settable(L, -3);
	}
	return 1;
}

int register_common_api(lua_State* L)
{
	lua_register(L, "base64_encode", api_base64_encode);
	lua_register(L, "base64_decode", api_base64_decode);
	lua_register(L, "NetaddrInConfig", api_netaddr_in_config);
	lua_register(L, "GameMessageUnpack", api_message_game_unpack);
	lua_register(L, "GameMessagePack", api_message_game_pack);
	lua_register(L, "md5_encode_string", api_md5_encode_string);
	lua_register(L, "md5_encode_file", api_md5_encode_file);
	lua_register(L, "StringSplit", api_string_split);
	return 0;
}
